package com.authine.cloudpivot.ext.applicationservice.organization;

import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.authine.cloudpivot.common.organization.model.OrganizationSourceConfig;
import com.authine.cloudpivot.common.organization.model.enums.SourceType;
import com.authine.cloudpivot.common.organization.model.enums.Status;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.constants.PlatformConst;
import com.authine.cloudpivot.ext.dto.kingDee.request.KingDeeOrganization;
import com.authine.cloudpivot.ext.dto.system.OrganizationDto;
import com.authine.cloudpivot.ext.dto.system.UserDto;
import com.authine.cloudpivot.ext.service.OrganizationDataService;
import com.authine.cloudpivot.ext.utils.BoResultFormat;
import com.authine.cloudpivot.ext.utils.BoServiceUtils;
import com.authine.cloudpivot.ext.utils.JdbcTemplateUtils;
import com.authine.cloudpivot.ext.utils.system.BeanUtils;
import com.authine.common.util.ObjectMapperUtils;
import com.authine.hermes.app.launcher.org.v2.OrganizationV2;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.authine.mvp.app.launcher.dto.errorcode.ErrorCodeEnum;
import com.authine.mvp.app.org.dto.domainmodel.UnitType;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.util.*;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * @ClassName OrganizationApi
 * @Description: 组织api接口
 * @Author fj
 * @Date 2021/7/2
 * @Version V1.0
 **/
@Path("OrganizationApi")
@Slf4j
public class OrganizationApi extends ApplicationService {
    public static final DepartmentApi departmentApi = new DepartmentApi();
    public static final UserApi userApi = new UserApi();
    public static final OrganizationDataService organizationDataService = new OrganizationDataService();

    /**
     * 根据查询条件获取组织是否存在
     *
     * @param param 请求参数
     * @return 查询结果总数
     */
    public Integer orgCount(Map<String, Object> param) {
        // 获取请求参数key
        String key = param.keySet().iterator().next();
        List<Map<String, Object>> orgList = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_ORGANIZATION).selectField("id, parent_id, account_id, business_member_id, transaction_organization_id," +
                "extends_attr, name, parent_name, business_member_name, description, role_names, organization_product_line, business_scope, license_code, credit_identifier," +
                "legal_representative, registered_capital, memo, purchase_quota, attachment, platform, `virtual`, statement_cycle, reconciliation_day_strategy, payment_day_strategy," +
                "small_scale, small_scale_rate, freight_ratio, pay_appoint_way, sales_area, major_brand, quotation_decimal_limit, level, enabled, connect, cellphone," +
                "email, qq, platform_id, platform_name, invite_user, goods_automatic_matching, muti_org_id, org_attributeValue, org_attributeName"))
                .eq(key, param.get(key))
                .queryForList();
        log.info("------------------------查询组织列表返回结果：{}------------------------", JSONObject.toJSONString(orgList));
        return orgList.size();
    }

    /**
     * 保存组织信息
     *
     * @param organization 组织信息
     */
    @Path("saveOrg")
    @POST
    @Operation(summary = "保存组织信息", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> saveOrg(@Parameter OrganizationDto organization) {
        // 判断组织信息是否存在
        String name = organization.getName();
        Map<String, Object> param = Maps.newHashMap();
        // 通过公司名称查询
        param.put("name", name);
        int count = this.orgCount(param);
        if (count > 0) {
            return SingleResponse.error("-1", "公司名称已存在");
        }

        // 判断父组织
        if (!CollectionUtils.isEmpty(organization.getParent_id())) {
            OrganizationDto parent = this.getOrgByIdThroughJDBC(OrganizationDto.builder().id(organization.getParent_id().get(0).getId()).build());
            if (parent == null) {
                throw new BizException("父组织不存在");
            }
            if (!CollectionUtils.isEmpty(parent.getParent_id())) {
                parent = this.getOrgByIdThroughJDBC(OrganizationDto.builder().id(parent.getParent_id().get(0).getId()).build());
                if (parent == null) {
                    throw new BizException("父组织的父组织不存在，请联系管理员");
                }
                if (!CollectionUtils.isEmpty(parent.getParent_id())) {
                    throw new BizException("组织最多仅支持3级");
                }
            }
        }

        // 设置平台id
        if (CollectionUtils.isEmpty(organization.getPlatform_id())) {
            SelectorFormat platForm = new SelectorFormat();
            platForm.setId(PlatformConst.ORGANIZATION_ID);
            platForm.setName(PlatformConst.ORGANIZATION_NAME);
            platForm.setType(UnitType.DEPARTMENT.getIndex());
            organization.setPlatform_id(Collections.singletonList(platForm));
        } else {
            OrganizationDto platForm = this.getOrgByIdThroughJDBC(OrganizationDto.builder().id(organization.getPlatform_id().get(0).getId()).build());
            if (!org.apache.commons.lang3.StringUtils.containsIgnoreCase(platForm.getRole_names(), PlatformConst.ROLE_PM_ADMIN)) {
                throw new BizException("平台id仅能选择平台组织");
            }
        }

        // 创建云枢组织
        setOrgValue(organization);

        OrganizationV2 organizationV2 = buildOrganizationV2(organization);
        organizationV2.setDepartmentId(organization.getId());
        log.info("------------------------新增云枢组织参数,组织信息：{}------------------------", JSONObject.toJSONString(organizationV2));

        SingleResponse<OrganizationV2> org = this.orgServiceV2.createOrganization(organizationV2);
        if (!org.isSuccess()) {
            return SingleResponse.error(org.getErrCode(), org.getErrMessage());
        }
        log.info("------------------------云枢组织数据新增成功,组织信息：{}------------------------", JSONObject.toJSONString(org.getData()));

        // 保存组织信息到系统管理中，id和云枢组织id保持同步
        organization.setId(org.getData().getDepartmentId());
        // 修改时需要同步到组织架构，保存组织id
        organization.setMuti_org_id(org.getData().getId());

        Map<String, Object> organizationMap = BeanUtils.bean2Map(organization);
        log.info("------------------------创建系统管理组织参数：{}------------------------", JSONObject.toJSONString(organizationMap));
        SingleResponse<BO> createOrganizationBO = BoServiceUtils.createBo(ModelConst.T_ORGANIZATION, Collections.singletonList(organizationMap));
        if (!createOrganizationBO.isSuccess()) {
            return SingleResponse.error("-4", "系统管理组织创建失败");
        }
        log.info("------------------------系统管理组织数据新增成功，组织信息：{}------------------------", JSONObject.toJSONString(createOrganizationBO));

        // 保存信息到金蝶中
        boolean customer = false;
        if (!StringUtils.isEmpty(organization.getRole_names())) {
            customer = organization.getRole_names().contains(PlatformConst.ROLE_CUSTOMER_ADMIN);
        }
        organizationDataService.createOrganization(KingDeeOrganization.builder()
                .id(createOrganizationBO.getData().getBizObjectId())
                .companyName(String.valueOf(createOrganizationBO.getData().getData().get("name")))
                .vendorAndCustomer(customer)
                .build());

        // todo 推送消息

        return createOrganizationBO;
    }

    /**
     * 更新组织信息
     *
     * @param organization 组织信息
     * @return 响应结果
     */
    @Path("updateOrg")
    @POST
    @Operation(summary = "更新组织信息", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateOrg(@Parameter OrganizationDto organization) {
        Assert.notNull(organization.getId(), "ID不能为空");
        Map<String, Object> param = Maps.newHashMap();
        if (!CollectionUtils.isEmpty(organization.getParent_id())) {
            if (organization.getId().equals(organization.getParent_id().get(0).getId())) {
                return SingleResponse.error("-1", "父组织不能为当前组织");
            }
            param.put("id", organization.getParent_id().get(0).getId());
            int orgCount = this.orgCount(param);
            if (orgCount == 0) {
                return SingleResponse.error("-2", "父组织不存在");
            }
        }
        OrganizationDto oldOrganization = this.getOrgByIdThroughJDBC(organization);
        log.info("------------------------修改之前的组织数据：{}------------------------", JSONObject.toJSONString(oldOrganization));
        // todo 平台id仅能选择平台组织

        setOrgValue(organization);

        // 修改云枢组织
        if (!organization.getName().equals(oldOrganization.getName()) || !organization.getParent_name().equals(oldOrganization.getParent_name())) {
            OrganizationV2 organizationV2 = buildOrganizationV2(organization);
            SingleResponse<OrganizationV2> org = this.orgServiceV2.updateOrganization(organizationV2);
            if (!org.isSuccess()) {
                return SingleResponse.error(org.getErrCode(), org.getErrMessage());
            }
        }
        // 系统管理组织修改
        Map<String, Object> organizationMap = BeanUtils.bean2Map(organization);
        log.info("------------------------修改系统管理组织参数：{}------------------------", JSONObject.toJSONString(organizationMap));
        SingleResponse<BO> updateOrganizationBO = BoServiceUtils.updateMainBo(ModelConst.T_ORGANIZATION, organizationMap);
        if (!updateOrganizationBO.isSuccess()) {
            return SingleResponse.error("-4", "系统管理组织修改失败");
        }
        // 记录组织修改记录
        JSONObject newOrganizationJSON = JSON.parseObject(JSON.toJSONString(organization, SerializerFeature.WRITE_MAP_NULL_FEATURES));
        log.info("------------------------修改之后的组织数据javaBean转为json：{}------------------------", JSONObject.toJSONString(oldOrganization));
        JSONObject oldOrganizationJSON = JSON.parseObject(JSON.toJSONString(oldOrganization, SerializerFeature.WRITE_MAP_NULL_FEATURES));
        log.info("------------------------修改之前的组织数据javaBean转为json：{}------------------------", JSONObject.toJSONString(oldOrganization));
        this.orgRecord(newOrganizationJSON, oldOrganizationJSON);
        // 修改组织名称后，同步修改部门和用户中的组织名称
        if (!newOrganizationJSON.getString("name").equals(oldOrganizationJSON.getString("name"))) {
            String oldOrgName = oldOrganizationJSON.getString("name");
            String newOrgName = newOrganizationJSON.getString("name");
            SelectorFormat orgSelectorFormat = new SelectorFormat();
            orgSelectorFormat.setType(1);
            orgSelectorFormat.setId(oldOrganizationJSON.getString("id"));
            orgSelectorFormat.setName(newOrgName);
            // 获取需要修改的部门
            List<Map<String, Object>> departmentListData = Lists.newArrayList();
            SingleResponse<BOList> departmentBOList = departmentApi.getDepartmentsByOrgName(oldOrgName);
            departmentBOList.getData().getData().forEach(map -> {
                Map<String, Object> departmentMap = Maps.newHashMap();
                departmentMap.put("id", map.get("id"));
                departmentMap.put("organization_id", orgSelectorFormat);
                departmentMap.put("organization_name", newOrgName);
                departmentListData.add(departmentMap);
            });
            log.info("------------------------当前组织下需要修改的部门信息：{}------------------------", JSONObject.toJSONString(departmentListData));
            if (departmentListData.size() > 0) {
                SingleResponse<BO> updateDepartmentBO = BoServiceUtils.updateMainBo(ModelConst.T_DEPARTMENT, departmentListData);
                if (!updateDepartmentBO.isSuccess()) {
                    return SingleResponse.error("-5", "系统管理修改组织下部门信息失败");
                }
            }
            // 获取需要修改的用户
            List<Map<String, Object>> userListData = Lists.newArrayList();
            SingleResponse<BOList> userBOList = userApi.getUsersByOrgName(oldOrgName);
            userBOList.getData().getData().forEach(map -> {
                Map<String, Object> userMap = Maps.newHashMap();
                userMap.put("id", map.get("id"));
                userMap.put("organization_id", orgSelectorFormat);
                userMap.put("organization_name", newOrgName);
                userListData.add(userMap);
            });
            log.info("------------------------当前组织下需要修改的用户信息：{}------------------------", JSONObject.toJSONString(userListData));
            if (userListData.size() > 0) {
                SingleResponse<BO> updateUserBO = BoServiceUtils.updateMainBo(ModelConst.T_USER, userListData);
                if (!updateUserBO.isSuccess()) {
                    return SingleResponse.error("-6", "系统管理修改组织下用户信息失败");
                }
            }
        }
        return updateOrganizationBO;
    }

    /**
     * 根据组织id获取组织信息
     *
     * @param param 组织信息
     * @return 组织信息
     */
    @Path("getOrg")
    @POST
    @Operation(summary = "根据组织id获取组织信息", tags = CUSTOM_SERVICE)
    public OrganizationDto getOrg(@Parameter OrganizationDto param) {
        Assert.notNull(param.getId(), "组织ID不能为空");
        SingleResponse<BOList> orgBO = BoServiceUtils.findListBySimple(ModelConst.T_ORGANIZATION, "id", param.getId());
        log.info("------------orgBO：{}------------",JSONObject.toJSONString(orgBO));
        if (orgBO.getData().getTotal() == 0) {
            throw new BizException("组织ID:" + param.getId() + "不存在");
        }
        OrganizationDto organizationDto = ObjectMapperUtils.fromJSON(JSONObject.toJSONString(orgBO.getData().getData().get(0)), OrganizationDto.class);
        log.info("------------------------根据组织id获取组织信息返回结果：{}------------------------", JSONObject.toJSONString(organizationDto));
        return organizationDto;
    }

    /**
     * 使用jdbc查询的方式获取组织信息
     *
     * @param param 组织信息
     * @return 组织信息
     */
    @Path("getOrgByIdThroughJDBC")
    @POST
    @Operation(summary = "使用jdbc查询的方式获取组织信息", tags = CUSTOM_SERVICE)
    public OrganizationDto getOrgByIdThroughJDBC(@Parameter OrganizationDto param) {
        Assert.notNull(param.getId(), "组织ID不能为空");
        OrganizationDto org = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_ORGANIZATION).selectField("id, parent_id, account_id, business_member_id, transaction_organization_id," +
                "extends_attr, name, parent_name, business_member_name, description, role_names, organization_product_line, business_scope, license_code, credit_identifier," +
                "legal_representative, registered_capital, memo, purchase_quota, attachment, platform, `virtual`, statement_cycle, reconciliation_day_strategy, payment_day_strategy," +
                "small_scale, small_scale_rate, freight_ratio, pay_appoint_way, sales_area, major_brand, quotation_decimal_limit, level, enabled, connect, cellphone," +
                "email, qq, platform_id, platform_name, invite_user, goods_automatic_matching, muti_org_id, org_attributeValue, org_attributeName"))
                .eq("id", param.getId())
                .queryForPOJO(OrganizationDto.class, true);
        if (org == null) {
            throw new BizException("组织ID:" + param.getId() + "不存在");
        }
        log.info("------------------------通过jdbc查询，根据组织id获取组织信息返回结果：{}------------------------", JSONObject.toJSONString(org));
        return org;
    }

    /**
     * 获取登录用户的组织信息
     *
     * @return 组织信息
     */
    @Path("getOrgByCorpLoginId")
    @POST
    @Operation(summary = "获取登录用户的组织信息", tags = CUSTOM_SERVICE)
    public OrganizationDto getOrgByCorpLoginId() {
        // 有些散户没有组织，故在此加上判断
        UserDto user = userApi.getUser(UserDto.builder().id(RequestContext.getCorpLoginId()).build());
        if (!CollectionUtils.isEmpty(user.getOrganization_id())) {
            OrganizationDto org = this.getOrgByIdThroughJDBC(OrganizationDto.builder().id(user.getOrganization_id().get(0).getId()).build());
            log.info("------------------------根据组织id获取组织信息返回结果：{}------------------------", JSONObject.toJSONString(org));
            return org;
        }
        return null;
    }

    /**
     * 根据多个组织id获取组织列表
     *
     * @param param 组织信息
     * @return 组织信息
     */
    @Path("getOrgListByOrgIds")
    @POST
    @Operation(summary = "根据多个组织id获取组织列表", tags = CUSTOM_SERVICE)
    public List<OrganizationDto> getOrgListByOrgIds(@Parameter OrganizationDto param) {
        Assert.notEmpty(param.getIds(), "组织ID不能为空");
        List<OrganizationDto> organizationList = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_ORGANIZATION).selectField("id, parent_id, account_id, business_member_id, transaction_organization_id," +
                "extends_attr, name, parent_name, business_member_name, description, role_names, organization_product_line, business_scope, license_code, credit_identifier," +
                "legal_representative, registered_capital, memo, purchase_quota, attachment, platform, `virtual`, statement_cycle, reconciliation_day_strategy, payment_day_strategy," +
                "small_scale, small_scale_rate, freight_ratio, pay_appoint_way, sales_area, major_brand, quotation_decimal_limit, level, enabled, connect, cellphone," +
                "email, qq, platform_id, platform_name, invite_user, goods_automatic_matching, muti_org_id, org_attributeValue, org_attributeName"))
                .in("id", param.getIds())
                .queryForPOJOList(OrganizationDto.class, true);
        log.info("------------查询组织列表返回结果：{}------------",JSONObject.toJSONString(organizationList));
        if (CollectionUtils.isEmpty(organizationList)) {
            return Lists.newArrayList();
        }
        return organizationList;
    }

    /**
     * 根据组织名称获取组织信息
     *
     * @param param 组织信息
     * @return 组织信息
     */
    @Path("getOrgByOrgName")
    @POST
    @Operation(summary = "根据组织名称获取组织信息", tags = CUSTOM_SERVICE)
    public OrganizationDto getOrgByOrgName(@Parameter OrganizationDto param) {
        Assert.notNull(param.getName(), "组织名称不能为空");
        SingleResponse<BOList> orgBO = BoServiceUtils.findListBySimple(ModelConst.T_ORGANIZATION, "name", param.getName());
        if (orgBO.getData().getTotal() == 0) {
            throw new BizException("组织名称:" + param.getName() + "不存在");
        }
        OrganizationDto organizationDto = ObjectMapperUtils.fromJSON(JSONObject.toJSONString(orgBO.getData().getData().get(0)), OrganizationDto.class);
        log.info("------------------------根据组织名称获取组织信息返回结果：{}------------------------", JSONObject.toJSONString(organizationDto));
        return organizationDto;
    }

    /**
     * 根据组织id获取集团中所有的组织(包含自身)
     *
     * @param param 组织信息
     * @return 组织信息
     */
    @Path("getOrgListByOrgId")
    @POST
    @Operation(summary = "根据组织id获取集团中所有的组织(包含自身)", tags = CUSTOM_SERVICE)
    public List<OrganizationDto> getOrgListByOrgId(@Parameter OrganizationDto param) {
        Assert.notNull(param.getId(), "组织id不能为空");

        List<OrganizationDto> organizationList = Lists.newArrayList();
        List<Map<String, Object>> orgList = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_ORGANIZATION).selectField("id, parent_id, account_id, business_member_id, transaction_organization_id," +
                "extends_attr, name, parent_name, business_member_name, description, role_names, organization_product_line, business_scope, license_code, credit_identifier," +
                "legal_representative, registered_capital, memo, purchase_quota, attachment, platform, `virtual`, statement_cycle, reconciliation_day_strategy, payment_day_strategy," +
                "small_scale, small_scale_rate, freight_ratio, pay_appoint_way, sales_area, major_brand, quotation_decimal_limit, level, enabled, connect, cellphone," +
                "email, qq, platform_id, platform_name, invite_user, goods_automatic_matching, muti_org_id, org_attributeValue, org_attributeName"))
                .eq("id", param.getId())
                .queryForList();
        if (CollectionUtils.isEmpty(orgList)) {
            throw new BizException("组织id:" + param.getName() + "不存在");
        }
        // 对结果进行格式化
        BoResultFormat.resultFormat(orgList, ModelConst.T_ORGANIZATION);
        OrganizationDto organizationDto = ObjectMapperUtils.fromJSON(JSONObject.toJSONString(orgList.get(0)), OrganizationDto.class);
        organizationList.add(organizationDto);
        // 通过parentId获取集团下所有子组织
        getOrgListByParentId(organizationDto.getId(), organizationList);

        log.info("------------------------根据组织id获取集团中所有的组织(包含自身)返回结果：{}------------------------", JSONObject.toJSONString(organizationList));
        return organizationList;
    }

    /**
     * 根据账户id获取对应的组织信息(可传多个账户id)
     *
     * @param param 账户id
     * @return 组织信息
     */
    @Path("getOrgListByAccountIds")
    @POST
    @Operation(summary = "根据账户id获取对应的组织信息(可传多个账户id)", tags = CUSTOM_SERVICE)
    public List<OrganizationDto> getOrgListByAccountIds(@Parameter OrganizationDto param) {
        Assert.notEmpty(param.getAccountIds(), "账户id不能为空");

        SingleResponse<BOList> orgBO = BoServiceUtils.findListByIn(ModelConst.T_ORGANIZATION, "account_id", param.getAccountIds());
        if (orgBO.getData().getTotal() == 0) {
            return Lists.newArrayList();
        }
        List<OrganizationDto> organizationList = ObjectMapperUtils.readValue(JSONObject.toJSONString(orgBO.getData().getData()), OrganizationDto.class);
        log.info("------------------------根据账户获取组织列表返回结果：{}------------------------", JSONObject.toJSONString(organizationList));
        return organizationList;
    }

    /**
     * 获取所有非指定的供应商组织列表(可传多个组织id)
     *
     * @param param 指定供应商id
     * @return 组织信息
     */
    @Path("getVendorOrgListNotIds")
    @POST
    @Operation(summary = "获取所有非指定的供应商组织列表(可传多个组织id)", tags = CUSTOM_SERVICE)
    public List<OrganizationDto> getVendorOrgListNotIds(@Parameter OrganizationDto param) {
        Assert.notEmpty(param.getIds(), "组织id不能为空");

        StringBuilder sqlBuilder = new StringBuilder();
        Map<String, Object> sqlParam = Maps.newHashMap();
        sqlBuilder.append("select o.id, o.parent_id, o.account_id, o.business_member_id, o.transaction_organization_id, o.extends_attr, o.`name`, o.parent_name, o.business_member_name, o.description, o.role_names, o.organization_product_line,\n" +
                "business_scope, o.license_code, o.credit_identifier, o.legal_representative, o.registered_capital, o.memo, o.purchase_quota, o.attachment, o.platform, o.`virtual`, o.statement_cycle, o.reconciliation_day_strategy,\n" +
                "payment_day_strategy, o.small_scale, o.small_scale_rate, o.freight_ratio, o.pay_appoint_way, o.sales_area, o.major_brand, o.quotation_decimal_limit, o.`level`, o.enabled, o.connect, o.cellphone, o.email, o.qq, o.platform_id,\n" +
                "platform_name, o.invite_user, o.goods_automatic_matching, o.muti_org_id\n");
        sqlBuilder.append("from\n");
        sqlBuilder.append(JdbcTemplateUtils.getTableName(ModelConst.T_ORGANIZATION));
        sqlBuilder.append(" as o\n");
        sqlBuilder.append("left join\n");
        sqlBuilder.append(JdbcTemplateUtils.getTableName(ModelConst.T_ROLE));
        sqlBuilder.append(" as r\n");
        sqlBuilder.append("on r.organization_id -> '$.id' = o.id\n");
        sqlBuilder.append("where o.deleted = 0\n");
        sqlBuilder.append("and o.id not in (:ids)\n");
        sqlParam.put("ids", param.getIds());
        sqlBuilder.append("and r.name = :roleName\n");
        sqlParam.put("roleName", PlatformConst.ROLE_VENDOR_ADMIN);
        log.info("sql = {}, parameters = {}", sqlBuilder, JSONObject.toJSONString(sqlParam));

        List<OrganizationDto> organizationList = JdbcTemplateUtils.queryForPOJOList(sqlBuilder.toString(), sqlParam, ModelConst.T_ORGANIZATION, OrganizationDto.class, true);
        log.info("------------------------获取所有非指定的供应商组织列表返回结果：{}------------------------", JSONObject.toJSONString(organizationList));
        return organizationList;
    }

    /**
     * 通过角色名称获取组织列表(可传多个角色名称)
     *
     * @param param 角色名称
     * @return 组织信息
     */
    @Path("getOrgListByRoleNames")
    @POST
    @Operation(summary = "通过角色名称获取组织列表(可传多个角色名称)", tags = CUSTOM_SERVICE)
    public List<OrganizationDto> getOrgListByRoleNames(@Parameter OrganizationDto param) {
        Assert.notEmpty(param.getRoleNames(), "角色名称不能为空");

        StringBuilder sqlBuilder = new StringBuilder();
        Map<String, Object> sqlParam = Maps.newHashMap();
        sqlBuilder.append("select o.id, o.parent_id, o.account_id, o.business_member_id, o.transaction_organization_id, o.extends_attr, o.`name`, o.parent_name, o.business_member_name, o.description, o.role_names, o.organization_product_line,\n" +
                "business_scope, o.license_code, o.credit_identifier, o.legal_representative, o.registered_capital, o.memo, o.purchase_quota, o.attachment, o.platform, o.`virtual`, o.statement_cycle, o.reconciliation_day_strategy,\n" +
                "payment_day_strategy, o.small_scale, o.small_scale_rate, o.freight_ratio, o.pay_appoint_way, o.sales_area, o.major_brand, o.quotation_decimal_limit, o.`level`, o.enabled, o.connect, o.cellphone, o.email, o.qq, o.platform_id,\n" +
                "platform_name, o.invite_user, o.goods_automatic_matching, o.muti_org_id\n");
        sqlBuilder.append("from\n");
        sqlBuilder.append(JdbcTemplateUtils.getTableName(ModelConst.T_ORGANIZATION));
        sqlBuilder.append(" as o\n");
        sqlBuilder.append("left join\n");
        sqlBuilder.append(JdbcTemplateUtils.getTableName(ModelConst.T_ROLE));
        sqlBuilder.append(" as r\n");
        sqlBuilder.append("on r.organization_id -> '$.id' = o.id\n");
        sqlBuilder.append("where o.deleted = 0\n");
        sqlBuilder.append("and r.deleted = 0\n");
        sqlBuilder.append("and r.name in (:roleNames)\n");
        sqlParam.put("roleNames", param.getRoleNames());
        log.info("sql = {}, parameters = {}", sqlBuilder, JSONObject.toJSONString(sqlParam));

        List<OrganizationDto> organizationList = JdbcTemplateUtils.queryForPOJOList(sqlBuilder.toString(), sqlParam, ModelConst.T_ORGANIZATION, OrganizationDto.class, true);
        log.info("------------------------通过角色名称获取组织列表返回结果：{}------------------------", JSONObject.toJSONString(organizationList));
        return organizationList;
    }

    /**
     * 根据父组织获取所有的自组织(非递归)
     *
     * @param parentId         父组织id
     * @param organizationList 组织列表
     */
    private void getOrgListByParentId(String parentId, List<OrganizationDto> organizationList) {
        Assert.notNull(parentId, "父组织id不能为空");
        // 通过parentId获取集团下所有子组织
        List<OrganizationDto> childOrganizationList = Objects.requireNonNull(JdbcTemplateUtils.builder(ModelConst.T_ORGANIZATION)
                .selectField("id, parent_id, account_id, business_member_id, transaction_organization_id, extends_attr, `name`, parent_name, business_member_name, description, role_names, organization_product_line,\n" +
                        "business_scope, license_code, credit_identifier, legal_representative, registered_capital, memo, purchase_quota, attachment, platform, `virtual`, statement_cycle, reconciliation_day_strategy,\n" +
                        "payment_day_strategy, small_scale, small_scale_rate, freight_ratio, pay_appoint_way, sales_area, major_brand, quotation_decimal_limit, `level`, enabled, connect, cellphone, email, qq, platform_id,\n" +
                        "platform_name, invite_user, goods_automatic_matching, muti_org_id"), ErrorCodeEnum.BIZ_EXCEPTION.getErrCode())
                .eq("parent_id -> '$.id'", parentId)
                .queryForPOJOList(OrganizationDto.class, true);
        log.info("------------------------根据组织id获取组织信息返回结果：{}------------------------", JSONObject.toJSONString(organizationList));
        if (!CollectionUtils.isEmpty(childOrganizationList)) {
            childOrganizationList.forEach(organization -> {
                organizationList.add(organization);
                getOrgListByParentId(organization.getId(), organizationList);
            });
        }
    }

    /**
     * 设置组织选人控件冗余名称
     *
     * @param organization 组织信息
     */
    private void setOrgValue(OrganizationDto organization) {
        if (!CollectionUtils.isEmpty(organization.getParent_id())) {
            organization.setParent_name(organization.getParent_id().get(0).getName());
        } else {
            organization.setParent_name("");
            organization.setParent_id(null);
        }
        if (!CollectionUtils.isEmpty(organization.getBusiness_member_id())) {
            organization.setBusiness_member_name(organization.getBusiness_member_id().get(0).getName());
        } else {
            organization.setBusiness_member_name("");
            organization.setBusiness_member_id(null);
        }
        if (!CollectionUtils.isEmpty(organization.getPlatform_id())) {
            organization.setPlatform_name(organization.getPlatform_id().get(0).getName());
        } else {
            organization.setPlatform_name("");
            organization.setPlatform_id(null);
        }
    }

    /**
     * 构建云枢组织对象
     *
     * @param organization 组织信息
     * @return 结果
     */
    private OrganizationV2 buildOrganizationV2(OrganizationDto organization) {
        OrganizationV2 organizationV2 = new OrganizationV2();
        organizationV2.setId(organization.getId());
        organizationV2.setName(organization.getName());
        organizationV2.setSourceType(SourceType.SELF_MAINTENANCE);
        organizationV2.setStatus(Status.ENABLE);
        organizationV2.setSourceConfig(new OrganizationSourceConfig());
        if (!CollectionUtils.isEmpty(organization.getParent_id())) {
            organizationV2.setParentDepartmentId(organization.getParent_id().get(0).getId());
        }
        return organizationV2;
    }

    /**
     * 组织修改记录
     *
     * @param newOrganizationJSON 修改之后的组织信息
     * @param oldOrganizationJSON 修改之前的组织信息
     */
    private void orgRecord(JSONObject newOrganizationJSON, JSONObject oldOrganizationJSON) {
        List<Map<String, Object>> orgRecordList = Lists.newArrayList();
        Map<String, Object> orgMap = Maps.newHashMap();
        SelectorFormat org = new SelectorFormat();
        org.setType(UnitType.DEPARTMENT.getIndex());
        org.setId(oldOrganizationJSON.getString("id"));
        org.setName(newOrganizationJSON.getString("name"));
        orgMap.put("organization_id", org);
        orgMap.put("organization_name", newOrganizationJSON.getString("name"));
        Set<String> keys = oldOrganizationJSON.keySet();
        for (String key : keys) {
            String oldValue = JSON.toJSONString(oldOrganizationJSON.get(key));
            String newValue = JSON.toJSONString(newOrganizationJSON.get(key));
            if (!oldValue.equals(newValue)) {
                Map<String, Object> recordMap = Maps.newHashMap(orgMap);
                recordMap.put("column_name", key);
                recordMap.put("old_value", oldValue.replaceAll("\"", ""));
                recordMap.put("new_value", newValue.replaceAll("\"", ""));
                orgRecordList.add(recordMap);
            }
        }
        log.info("------------------------系统管理组织修改记录：{}------------------------", JSONObject.toJSONString(orgRecordList));
        BoServiceUtils.createBo(ModelConst.T_ORGANIZATION_RECORD, orgRecordList);
    }
}
